package com.zhiche.lisa.tms.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.config.TmsProperties;
import com.zhiche.lisa.core.enums.IntegrationURIEnum;
import com.zhiche.lisa.core.enums.InterfaceEventEnum;
import com.zhiche.lisa.core.enums.SystemEnum;
import com.zhiche.lisa.core.enums.TableStatusEnum;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import com.zhiche.lisa.core.utils.geo.util.GeoUtil;
import com.zhiche.lisa.core.utils.geo.util.Point;
import com.zhiche.lisa.core.utils.redislog.RedisLogUtil;
import com.zhiche.lisa.oms.dao.model.Order;
import com.zhiche.lisa.oms.dto.HuiyuncheCancleDTO;
import com.zhiche.lisa.oms.dto.TransportationTypeDTO;
import com.zhiche.lisa.oms.service.ILocationService;
import com.zhiche.lisa.oms.service.IOrderService;
import com.zhiche.lisa.oms.vo.LocationVo;
import com.zhiche.lisa.tms.dao.mapper.ShipmentMapper;
import com.zhiche.lisa.tms.dao.model.*;
import com.zhiche.lisa.tms.dao.model.bo.*;
import com.zhiche.lisa.tms.dto.*;
import com.zhiche.lisa.tms.service.*;
import com.zhiche.lisa.tms.vo.ShipmentListInfoVo;
import com.zhiche.lisa.tms.vo.ShipmentListVo;
import com.zhiche.lisa.tms.vo.ShipmentVo;
import com.zhiche.lisa.util.ErpUtil;
import com.zhiche.lisa.util.MdmUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 装车单 服务实现类
 * </p>
 *
 * @author qichao
 * @since 2018-06-18
 */
@Service
public class ShipmentServiceImpl extends ServiceImpl<ShipmentMapper, Shipment> implements IShipmentService {

    private Logger LOGGER = LoggerFactory.getLogger(IShipmentService.class);

    @Autowired
    private IShipTaskService shipTaskService;
    @Autowired
    private IShipmentPositionService shipmentPositionService;
    @Autowired
    private IShipmentDetailService shipmentDetailService;
    @Autowired
    private IShipOrderItemService orderItemService;
    @Autowired
    IOrderService orderService;
    @Autowired
    private ErpUtil erpUtil;
    @Autowired
    private TmsProperties properties;
    @Autowired
    private ILocationService locationService;
    @Autowired
    private IOtmOrderReleaseService orderReleaseService;
    @Autowired
    private MdmUtil mdmUtil;

    @Value("${lisa.lspm.isUnlcnFleetDriverUrl}")
    private String isUnlcnFleetDriverUrl;

    @Value("${integration.getPriceAndMilesUrl}")
    private String getPriceAndMilesUrl;
    @Value("${security.jwt.header}")
    private String header;
    @Value("${lisa.lspm.queryDriverBasic}")
    private String queryDriverBasicUrl;
    @Value("${integration.queryListOriginationUrl}")
    private String queryListOriginationUrl;
    @Value("${integration.sendXMLShipToProvince}")
    private String sendXMLShipToProvinceUrl;
    @Value("${lisa.bms.importPurchaseAndDtl}")
    private String importPurchaseAndDtl;
    @Value("${lisa.socketTimeout}")
    private int socketTimeout;
    @Value("${lisa.lspm.getFleetListByLspMobileUrl}")
    private String getFleetListByLspMobileUrl;
    @Value("${logRedis.isTest}")
    private boolean isTest;
    @Override
    public Page<ShipmentListVo> getShipmentListVoByDriverId(Page<Shipment> page, HttpServletRequest request) {
        Page<ShipmentListVo> pageVo = new Page<>();
        List<ShipmentListVo> shipmentListVos = Lists.newArrayList();
        page.setAsc(false);
        page.setOrderByField("gmt_create");
        Map<String, Object> condition = page.getCondition();
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("登录超时,请重新登录");
        }
        Object driverId = condition.get("driverId");
        if (Objects.isNull(driverId) || StringUtils.isEmpty(driverId.toString())) {
            throw new BaseException("登录超时,请重新登录");
        }
        EntityWrapper<Shipment> ew = new EntityWrapper<>();
        ew.eq("driver_id", condition.get("driverId").toString());
        ew.eq("is_delete",0);


        String issue = (String) page.getCondition().get("issue");
        String arrive = (String) page.getCondition().get("arrive");
        // 发运状况
        if(!StringUtils.isEmpty(issue)){
            if((TableStatusEnum.STATUS_Y.getCode()).equals(issue)){
                ew.isNotNull("gmt_setoff");
            }else {
                ew.isNull("gmt_setoff");
            }
        }
        // 运抵状况
        if(!StringUtils.isEmpty(arrive)){
            if((TableStatusEnum.STATUS_Y.getCode()).equals(arrive)){
                ew.isNotNull("gmt_deliver");
            }else {
                ew.isNull("gmt_deliver");
            }
        }

        List<Shipment> shipments = baseMapper.getShipmentByPageNoTenant(page, ew);
        shipments.forEach(shipment -> {
            ShipmentListVo shipmentListVo = new ShipmentListVo();
            BeanUtils.copyProperties(shipment, shipmentListVo);
            List<ShipTaskCountBo> shipTaskCountBos = shipTaskService.getShipTaskCountByShipId(shipment.getCode());
            if (!CollectionUtils.isEmpty(shipTaskCountBos)) {
                shipTaskCountBos.forEach(shipTaskCountBo -> {
                    LocationVo start = locationService.getDriverLocationById(Long.parseLong(shipTaskCountBo.getOriginLocationCode()));
                    LocationVo end = locationService.getDriverLocationById(Long.parseLong(shipTaskCountBo.getDestLocationCode()));
                    if (!Objects.isNull(start)) {
                        shipTaskCountBo.setStartAddress(start.getLabel());
                    }
                    if (!Objects.isNull(end)) {
                        shipTaskCountBo.setEndAddress(end.getLabel());
                    }
                    shipTaskCountBo.setGmtSetoff(shipment.getGmtSetoff());
                    shipTaskCountBo.setGmtDeliver(shipment.getGmtDeliver());
                });
            }

            shipmentListVo.setShipTaskCountBos(shipTaskCountBos);

            shipmentListVos.add(shipmentListVo);
        });
        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(shipmentListVos);
        return pageVo;
    }

    @Override
    public ShipmentVo getShipDeteailById(Long shipmentId, HttpServletRequest request) {
        String authHeader = request.getHeader(header);

        ShipmentVo shipmentVo = null;
        Shipment shipment = this.selectById(shipmentId);
        if (!Objects.isNull(shipment)) {
            shipmentVo = new ShipmentVo();
            shipmentVo.setId(shipment.getId());
            shipmentVo.setCode(shipment.getCode());
            List<ShipTaskBo> shipTaskBos = shipTaskService.getShipTaskByShipId(shipmentId);
            if (!CollectionUtils.isEmpty(shipTaskBos)) {
                shipTaskBos.forEach(shipTaskBo -> {
                    LocationVo start = locationService.getDriverLocationById(Long.parseLong(shipTaskBo.getOriginLocationCode()));
                    LocationVo end = locationService.getDriverLocationById(Long.parseLong(shipTaskBo.getDestLocationCode()));
                    if (!Objects.isNull(start)) {
                        shipTaskBo.setStartAddress(start.getValue());
                    }
                    if (!Objects.isNull(end)) {
                        shipTaskBo.setEndAddress(end.getValue());
                    }
                    List<ShipOrderItemBo> shipOrderItemBos = shipTaskBo.getShipOrderItemBos();
                    List<ShipOrderItemCountBo> shipOrderItemCountBos = getShipOrderItemCountBos(shipOrderItemBos);

//                    if(!CollectionUtils.isEmpty(shipOrderItemBos)){
//                        shipOrderItemBos.forEach(shipOrderItemBo -> {
//                            Long orderItemId = shipOrderItemBo.getOrderItemId();
//                            OrderItemVo orderItem = orderUtil.getOrderItemById(authHeader,orderItemId);
//                            if(!Objects.isNull(orderItem)){
//                                shipOrderItemBo.setUom(orderItem.getUom());
//                                shipOrderItemBo.setAmount(orderItem.getAmount());
//                                shipOrderItemBo.setIssueItemId(orderItem.getIssueItemId());
//                            }
//                        });

//                        //根据货物名称进行分组汇总
//                        Map<String, Long> counting = shipOrderItemBos.stream().collect(
//                                Collectors.groupingBy(ShipOrderItemBo::getIssueItemId, Collectors.counting()));
//
//                        for (Map.Entry<String, Long> param : counting.entrySet()) {
//                            ShipOrderItemCountBo shipOrderItemCountBo = new ShipOrderItemCountBo();
//                            shipOrderItemCountBo.setIssueItemId(param.getKey());
//                            shipOrderItemCountBo.setAmount(param.getValue());
//                            shipOrderItemCountBos.add(shipOrderItemCountBo);
//                        }
//                    }

                    shipTaskBo.setShipOrderItemCountBos(shipOrderItemCountBos);

                });
            }
            shipmentVo.setShipTaskBos(shipTaskBos);
        }

        return shipmentVo;

    }

    @Override
    public ShipmentVo getDriverShipDeteailById(Long shipmentId, HttpServletRequest request) {
        String authHeader = request.getHeader(header);
        ShipmentVo shipmentVo = null;
        Shipment shipment = baseMapper.getDriverShipmentnotenant(shipmentId);
        if (!Objects.isNull(shipment)) {
            shipmentVo = new ShipmentVo();
            shipmentVo.setId(shipment.getId());
            shipmentVo.setCode(shipment.getCode());
            List<ShipTaskBo> shipTaskBos = shipTaskService.getShipTaskByShipIdNoTenant(shipmentId);
            if (!CollectionUtils.isEmpty(shipTaskBos)) {
                shipTaskBos.forEach(shipTaskBo -> {
                    LocationVo start = locationService.getDriverLocationById(Long.parseLong(shipTaskBo.getOriginLocationCode()));
                    LocationVo end = locationService.getDriverLocationById(Long.parseLong(shipTaskBo.getDestLocationCode()));
                    if (!Objects.isNull(start)) {
                        shipTaskBo.setStartAddress(start.getValue());
                    }
                    if (!Objects.isNull(end)) {
                        shipTaskBo.setEndAddress(end.getValue());
                    }
                    List<ShipOrderItemBo> shipOrderItemBos = shipTaskBo.getShipOrderItemBos();
                    List<ShipOrderItemCountBo> shipOrderItemCountBos = getShipOrderItemCountBos(shipOrderItemBos);
                    shipTaskBo.setShipOrderItemCountBos(shipOrderItemCountBos);

                });
            }
            shipmentVo.setShipTaskBos(shipTaskBos);
        }

        return shipmentVo;

    }

    private List<ShipOrderItemCountBo> getShipOrderItemCountBos(List<ShipOrderItemBo> shipOrderItemBos) {
        List<ShipOrderItemCountBo> shipOrderItemCountBoList = Lists.newArrayList();
        for (ShipOrderItemBo shipOrderItemBo : shipOrderItemBos) {

            if (StringUtils.isEmpty(shipOrderItemBo.getMaterial()) &&
                    StringUtils.isEmpty(shipOrderItemBo.getIssueItemId())) {
                shipOrderItemBo.setMaterial("其他(无车型及车架号)");
            } else if (StringUtils.isEmpty(shipOrderItemBo.getMaterial())
                    && !StringUtils.isEmpty(shipOrderItemBo.getIssueItemId())) {
                shipOrderItemBo.setMaterial(shipOrderItemBo.getIssueItemId());
            }

            ShipOrderItemCountBo shipOrderItemCountBo = getShipOrderItemCountBo(shipOrderItemCountBoList,
                    shipOrderItemBo);
            if (Objects.nonNull(shipOrderItemCountBo)) {
                shipOrderItemCountBo.setAmount(shipOrderItemCountBo.getAmount() + 1);
            } else {

                shipOrderItemCountBo = new ShipOrderItemCountBo();
                shipOrderItemCountBo.setIssueItemId(shipOrderItemBo.getMaterial());
                shipOrderItemCountBo.setAmount(1);
                shipOrderItemCountBoList.add(shipOrderItemCountBo);
            }
        }
        return shipOrderItemCountBoList;
    }

    private ShipOrderItemCountBo getShipOrderItemCountBo(List<ShipOrderItemCountBo> shipOrderItemCountBoList,
                                                         ShipOrderItemBo shipOrderItemBo) {
        for (ShipOrderItemCountBo shipOrderItemCountBo : shipOrderItemCountBoList) {
            if (!StringUtils.isEmpty(shipOrderItemBo.getMaterial()) &&
                    shipOrderItemCountBo.getIssueItemId().equals(shipOrderItemBo.getMaterial())) {
                return shipOrderItemCountBo;
            }
        }
        return null;
    }

    @Override
    @Transactional
    public void shipToByLicense(ShipToByLicenseBO shipToByLicenseBO, String token) {
        checkData(shipToByLicenseBO);
        // 查询装车单车牌号
        Shipment shipment = baseMapper.getDriverShipmentnotenant(shipToByLicenseBO.getShipmentId());
        if (shipment == null) {
            throw new BaseException(-1, "找不到对应装运单信息，请确认！");
        }
        if (shipment.getGmtDeliver() != null) {
            throw new BaseException(-1, "该单据已运抵，不能重复操作！");
        }
        ErpShipToByLicenseBO erpShipToByLicenseBO = new ErpShipToByLicenseBO();
        // 车牌号
        erpShipToByLicenseBO.setLicense(shipment.getTransportationId());
        // 司机名称
        erpShipToByLicenseBO.setDriverName(shipment.getDriverName());
        // 司机电话
        erpShipToByLicenseBO.setMobile(shipment.getDriverPhone());
        // 省份
        erpShipToByLicenseBO.setProvince(shipToByLicenseBO.getProvince());
        // 城市
        erpShipToByLicenseBO.setCity(shipToByLicenseBO.getCity());
        // 经度
        erpShipToByLicenseBO.setDcx(shipToByLicenseBO.getDcx());

        Point point = new Point(shipToByLicenseBO.getDcx(), shipToByLicenseBO.getDcy());
        Point src_ = GeoUtil.convertMars2Earth(point);
        // 经度
        erpShipToByLicenseBO.setDcx(src_.getLon());
        // 纬度
        erpShipToByLicenseBO.setDcy(src_.getLat());
        //调度指令订单号
        erpShipToByLicenseBO.setVcshipno(shipment.getShipSourceKey());

        // 发送运抵请求给 erp
        if (properties.isSendToERP()) {
            erpUtil.shipToByLicense(erpShipToByLicenseBO);
        }
        // 更新装车单实际交付时间
        Shipment updateShipment = new Shipment();
        updateShipment.setId(shipToByLicenseBO.getShipmentId());
        if(null != shipToByLicenseBO.getGmtFinish()){
            updateShipment.setGmtDeliver(shipToByLicenseBO.getGmtFinish());
            shipment.setGmtDeliver(shipToByLicenseBO.getGmtFinish());
        }else {
            updateShipment.setGmtDeliver(new Date());
            shipment.setGmtDeliver(new Date());
        }
        updateById(updateShipment);
        List<NameValuePair> headNamePairs = Lists.newArrayList();
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
        LOGGER.info("result (判断司机是否是中联自有车队请求参数) url:{},param:{}", isUnlcnFleetDriverUrl, shipment.getDriverId());
        String result = HttpClientUtil.get(isUnlcnFleetDriverUrl + "/" + shipment.getDriverId(), headNamePairs, null, properties.getSocktTimeOut());
        LOGGER.info("result (判断司机是否是中联自有车队返回结果) url:{},erpResult:{}", isUnlcnFleetDriverUrl + "/" + shipment.getDriverId(), result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String data = jsonObject.getString("data");
        if (!StringUtils.isEmpty(data)) {
            String xmlProv = getXmlProv(shipment, token);
            ArrayList<NameValuePair> headers = Lists.newArrayList();
            headers.add(new BasicNameValuePair("Authorization", token));
            HashMap<String, String> params = Maps.newHashMap();
            params.put("xml", xmlProv);
            params.put("sourceKey", shipment.getShipSourceKey());
            LOGGER.info("推送无车承运人信息--start url:{},param:{}", properties.getIntegrationhost() + sendXMLShipToProvinceUrl, xmlProv);
            if (!StringUtils.isEmpty(xmlProv)) {
                new Thread(() -> {
                    RedisLogUtil.addSysLogs(SystemEnum.OMS.getCode(),SystemEnum.INTEGRATION.getCode(),"无车承运人推送省"+shipment.getShipSourceKey(), JSON.toJSONString(params),"/tmsAPI/sendXMLShipToProv",1,1,null,isTest);
                    String res = HttpClientUtil.post(properties.getIntegrationhost() + sendXMLShipToProvinceUrl, headers, params, properties.getSocktTimeOut());
                    LOGGER.info("推送无车承运人信息--start url:{},key:{},result:{}", properties.getIntegrationhost() + sendXMLShipToProvinceUrl, shipment.getShipSourceKey(), res);
                }).start();

            }
        }
    }

    private String getXmlProv(Shipment shipment, String token) {
        // 查找指令
        EntityWrapper<OtmOrderRelease> orEW = new EntityWrapper<>();
        orEW.eq("shipment_gid", shipment.getShipSourceKey())
                .ne("status", TableStatusEnum.STATUS_50.getCode())
                .orderBy("id", false);
        List<OtmOrderRelease> releases = orderReleaseService.selectList(orEW);
        if (CollectionUtils.isNotEmpty(releases)) {
            ArrayList<NameValuePair> headers = Lists.newArrayList();
            headers.add(new BasicNameValuePair("Authorization", token));
            HashMap<String, String> params = Maps.newHashMap();
            params.put("driverId", shipment.getDriverId());
            String paramJson = JSONObject.toJSONString(params);
            LOGGER.info("TMS无车承运人获取司机信息--->url:{},param:{}", queryDriverBasicUrl, paramJson);
            String res = "";
            try {
                res = HttpClientUtil.postJson(queryDriverBasicUrl, headers, paramJson, properties.getSocktTimeOut());
                LOGGER.info("TMS无车承运人获取司机信息--->result:{}", res);
            } catch (Exception e) {
                LOGGER.error("TMS无车承运人获取司机信息--->超时失败:{}", e);
            }
            DriverBasicDTO basicInfo = null;
            OtmOrderRelease order = releases.get(0);
            DriverLicense verifyLicense = null;
            LspLicense lspLicense = null;
            CarrierLicense carrierLicense = null;
            Origination origin = null;
            Origination dest = null;
            if (!StringUtils.isEmpty(res)) {
                RestfulResponse<DriverBasicDTO> response = JSONObject.parseObject(res, new TypeReference<RestfulResponse<DriverBasicDTO>>() {
                });
                if (response != null && TableStatusEnum.STATUS_0.getCode().equals(String.valueOf(response.getCode()))) {
                    basicInfo = response.getData();
                    if (basicInfo != null) {
                        List<DriverLicense> licenseList = basicInfo.getDriverLicenseList();
                        // 找到司机从业资格证
                        if (CollectionUtils.isNotEmpty(licenseList)) {
                            for (DriverLicense dl : licenseList) {
                                if (dl.getLicenseTypeId() != null
                                        && (dl.getLicenseTypeId() == 1L || dl.getLicenseTypeId() == 3L)
                                        && !StringUtils.isEmpty(dl.getLicenseId())) {
                                    verifyLicense = dl;
                                }
                            }
                        }
                        // 找到道路运输许可证(承运商)
                        List<LspLicense> lspLicenses = basicInfo.getLspLicenses();
                        if (CollectionUtils.isNotEmpty(lspLicenses)) {
                            for (LspLicense ll : lspLicenses) {
                                if (ll.getLicenseTypeId() != null
                                        && ll.getLicenseTypeId() == 5L
                                        && !StringUtils.isEmpty(ll.getLicenseId())) {
                                    lspLicense = ll;
                                }
                            }
                        }
                        // 找到车辆的道路许可证
                        List<CarrierLicense> carrierLicenses = basicInfo.getCarrierLicenses();
                        if (CollectionUtils.isNotEmpty(carrierLicenses)) {
                            for (CarrierLicense cl : carrierLicenses) {
                                if (cl.getLicenseTypeId() != null
                                        && cl.getLicenseTypeId() == 9L
                                        && !StringUtils.isEmpty(cl.getLicenseId())) {
                                    carrierLicense = cl;
                                }
                            }
                        }
                    }
                }
            }

            //获取启运地标准编码
            HashMap<String, String> originParam = Maps.newHashMap();
            originParam.put("province", order.getOriginLocationProvince());
            originParam.put("city", order.getOriginLocationCity());
            originParam.put("county", order.getOriginLocationCounty());
            String originPJSON = JSONObject.toJSONString(originParam);
            String resLocation = HttpClientUtil.postJson(properties.getIntegrationhost() + queryListOriginationUrl, headers, originPJSON, properties.getSocktTimeOut());
            origin = getOrigination(origin, resLocation);
            HashMap<String, String> destParam = Maps.newHashMap();
            destParam.put("province", order.getDestLocationProvince());
            destParam.put("city", order.getDestLocationCity());
            destParam.put("county", order.getDestLocationCounty());
            String destPJSON = JSONObject.toJSONString(destParam);
            String resDest = HttpClientUtil.postJson(properties.getIntegrationhost() + queryListOriginationUrl, headers, destPJSON, properties.getSocktTimeOut());
            dest = getOrigination(dest, resDest);


            Map<String, BigDecimal> result = new HashMap<>();
            Map<String, String> orderno = new HashMap<>();
            orderno.put("orderno", order.getReleaseGid());
            List<NameValuePair> headNamePairs = Lists.newArrayList();
            headNamePairs.add(new BasicNameValuePair("Authorization", token));
            String orderJSON = JSONObject.toJSONString(orderno);
            LOGGER.info("无车承运人 priceAndMiles url:{},param:{}", properties.getIntegrationhost() + getPriceAndMilesUrl, orderJSON);
            String priceAndMiles = HttpClientUtil.postJson(properties.getIntegrationhost() + getPriceAndMilesUrl, headNamePairs,
                    orderJSON, properties.getSocktTimeOut());
            LOGGER.info("无车承运人 priceAndMiles param:{}, result {}", orderJSON, priceAndMiles);
            if (!StringUtils.isEmpty(priceAndMiles)) {
                JSONObject parseObject = JSONObject.parseObject(priceAndMiles);
                LOGGER.info("解析价格和里程 priceAndMiles data:{}", parseObject);
                if (parseObject.getIntValue("code") == 0) {
                    //暂估价
                    BigDecimal price = parseObject.getJSONObject("data").getBigDecimal("price");
                    BigDecimal miles = parseObject.getJSONObject("data").getBigDecimal("miles");
                    result.put("price", price);
                    //计价里程
                    result.put("miles", miles);
                    result.put("total", price.multiply(miles));
                    LOGGER.info("封装价格跟里程 priceAndMiles data:{}", result);
                }
            }
            LOGGER.info("设置无车承运人参数 basicInfo:{},verifyLicense:{},lspLicense:{},carrierLicense:{},origin:{},dest:{},result:{}",
                    basicInfo,verifyLicense,lspLicense,carrierLicense,origin,dest,result);
            if (basicInfo != null
                    && verifyLicense != null
                    && lspLicense != null
                    && carrierLicense != null
                    && origin != null
                    && dest != null
                    && !result.isEmpty()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                StringBuilder sb = new StringBuilder();
                sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                sb.append("<root>");
                sb.append("<header>");
                sb.append("<methodIdentifier>SyncStOrderService.add</methodIdentifier>");
                sb.append("</header>");
                sb.append("<body>");
                sb.append("<stOrder>");
                // 司机信息
                sb.append("<stDriver>");
                sb.append("<nameOfPerson> ").append(basicInfo.getName()).append("</nameOfPerson>");// 司机姓名*
                sb.append("<qualificationCertificateNumber>").append(verifyLicense.getLicenseId()).append("</qualificationCertificateNumber>"); // 司机从业资格证号*
                sb.append("<qualificationCertificateType>经营性道路货物运输驾驶员</qualificationCertificateType>");// 司机从业资格证类型*
                sb.append("<telephoneNumber>").append(basicInfo.getMobile()).append("</telephoneNumber>");// 司机电话
                sb.append("<aduitTime>").append(sdf.format(basicInfo.getGmtCreate())).append("</aduitTime>");// 司机通过平台审核的日期*
                sb.append("</stDriver>");
                // 货物信息
                sb.append("<stOrderGoods>");
                sb.append("<descriptionOfGoods>").append(StringUtils.isEmpty(order.getStanVehicleType()) ? "商品车" : order.getStanVehicleType()).append("</descriptionOfGoods>"); // 货物名称*
                sb.append("<cargoTypeClassificationCode>999</cargoTypeClassificationCode>"); // 货物类型*
                sb.append("<goodsItemGrossWeight>" + 1500.000 + "</goodsItemGrossWeight>"); // 货物毛重*
                sb.append("<cube></cube>"); // 体积
                sb.append("<totalNumberOfPackages></totalNumberOfPackages>"); // 总件数
                sb.append("</stOrderGoods>");

                // 其他
                sb.append("<carrier>深圳市康舶司科技有限公司</carrier>");
                sb.append("<consignmentDateTime>").append(sdf.format(order.getGmtCreate())).append("</consignmentDateTime>"); //托运日期时间
                sb.append("<originalDocumentNumber>").append(order.getCusWaybillNo()).append("</originalDocumentNumber>"); // 上游企业委托运输单号
                // 托运单号
                sb.append("<shippingNoteNumber>").append(order.getCusOrderNo()).append("</shippingNoteNumber>");
                sb.append("<despatchActualDateTime>").append(sdf.format(shipment.getWmsShipTime() == null ? shipment.getGmtSetoff() : shipment.getWmsShipTime())).append("</despatchActualDateTime>"); // 发运实际日期时间
                sb.append("<goodsReceiptDateTime>").append(sdf.format(shipment.getGmtDeliver())).append("</goodsReceiptDateTime>"); // 收货日期时间
                sb.append("<placeOfLoadingDeliProvince>").append(order.getOriginLocationProvince()).append("</placeOfLoadingDeliProvince>"); // 装货地点-省份
                sb.append("<placeOfLoadingDeliCity>").append(order.getOriginLocationCity()).append("</placeOfLoadingDeliCity>"); // 装货地点-地市
                sb.append("<placeOfLoadingDeliDistrict>").append(order.getOriginLocationCounty()).append("</placeOfLoadingDeliDistrict>"); // 装货地点-区县
                sb.append("<deliCountrySubdivisionCode>").append(StringUtils.isEmpty(origin.getCountyCode()) ? origin.getCityCode() : origin.getCountyCode()).append("</deliCountrySubdivisionCode>"); // 装货地点-区划代码
                sb.append("<goodsReceiptPlaceProvince>").append(order.getDestLocationProvince()).append("</goodsReceiptPlaceProvince>"); // 收货地点-省份
                sb.append("<goodsReceiptPlaceCity>").append(order.getDestLocationCity()).append("</goodsReceiptPlaceCity>"); // 收货地点-地市
                sb.append("<goodsReceiptPlaceDistrict>").append(order.getDestLocationCounty()).append("</goodsReceiptPlaceDistrict>"); // 收货地点-区县
                sb.append("<receiptCountrySubdivisionCode>").append(StringUtils.isEmpty(dest.getCountyCode()) ? dest.getCityCode() : dest.getCountyCode()).append("</receiptCountrySubdivisionCode>"); // 收货地点-区划代码
                sb.append("<businessTypeCode>1003999</businessTypeCode>"); // 业务类型代码
                //sb.append("<travelDistance>" + getReportDataResponseModel.getKm() + "</travelDistance>"); // 行驶距离（公里）
                sb.append("<transportDistance>").append((StringUtils.isEmpty(result.get("miles")) ? "1.00" : String.format("%.2f", result.get("miles")))).append("</transportDistance>"); // 运输距离（公里）*
                sb.append("<typeOfshipping>公路运输</typeOfshipping>"); // 运输方式 *
                sb.append("<transportationComb>传统运输</transportationComb>"); //运输组织 *
                sb.append("<totalMonetaryAmount>").append(String.format("%.2f", result.get("total"))).append("</totalMonetaryAmount>"); //货币总金额（元）*
                sb.append("<remark></remark>");
                sb.append("<consignor>中联中国</consignor>"); // 发货人
                sb.append("<personalIdentityDocument></personalIdentityDocument>"); //个人证件号
                sb.append("<consignee>").append(order.getDestLocationAddress()).append("</consignee>"); //收货人
                sb.append("<pstatus>0</pstatus>"); // 运单标记 0表示需上传国家平台，-1表示无需上传国家平台
                sb.append("<actualCarrier>").append(shipment.getLspName()).append("</actualCarrier>"); // 实际承运人信息-实际承运人
                sb.append("<actualType>").append((StringUtils.isEmpty(shipment.getLspName()) && shipment.getLspName().endsWith("公司")) ? "公司" : "个体").append("</actualType>"); // 实际承运人信息-企业类型
                sb.append("<carrierRegisterPlace>").append(basicInfo.getLspRegisterAddr()).append("</carrierRegisterPlace>"); // 实际承运人信息-注册地
                sb.append("<carrierPermitNumber>").append(lspLicense.getLicenseId()).append("</carrierPermitNumber>"); // 实际承运人信息-道路运输经营许可证编号
                sb.append("<carrierBusinessRange>普通货运</carrierBusinessRange>"); // 实际承运人信息-道路运输经营范围
                sb.append("<carrierAduitTime>").append(sdf.format(basicInfo.getLspCreate())).append("</carrierAduitTime>"); // 实际承运人信息-通过平台审核日期
                sb.append("<vehicleNumber>").append(shipment.getTransportationId()).append("</vehicleNumber>"); //营运车辆信息-车辆牌照号
                sb.append("<licensePlateTypeCode>01</licensePlateTypeCode>"); //营运车辆信息-牌照类型代码
                sb.append("<roadTransportCertificateNumber>").append(carrierLicense.getLicenseId()).append("</roadTransportCertificateNumber>"); //营运车辆信息-道路运输证号
                sb.append("<vehicleTonnage>").append((StringUtils.isEmpty(basicInfo.getCarrierSelfWeight()) ? "55.000" : String.format("%.3f", new BigDecimal(basicInfo.getCarrierSelfWeight())))).append("</vehicleTonnage>"); //营运车辆信息-车辆载质量（吨）
                sb.append("<trailerVehiclePlateNumber>").append(basicInfo.getTrailerPlate()).append("</trailerVehiclePlateNumber>");// 营运车辆信息-挂车牌照号
                sb.append("<vehicleAnchored>").append(basicInfo.getLspName()).append("</vehicleAnchored>"); // 营运车辆信息-挂靠实际承运人
                sb.append("<vehicleClassificationCode>X91</vehicleClassificationCode>"); //营运车辆信息-车辆分类代码
                sb.append("<owner>").append(StringUtils.isEmpty(basicInfo.getCarrierOwner()) ? basicInfo.getName() : basicInfo.getCarrierOwner()).append("</owner>"); // 营运车辆信息-车辆所有人
                sb.append("<operatingPermitNumber> ").append(lspLicense.getLicenseId()).append("</operatingPermitNumber>"); //营运车辆信息-许可证编号
                sb.append("<vehicleAduitTime>").append(sdf.format(basicInfo.getCarrierCreate())).append("</vehicleAduitTime>"); //营运车辆信息-通过平台审核日期
                sb.append("<vehicleIsAccident></vehicleIsAccident>"); // 运输产生安全事故-是否发生
                sb.append("<vehicleIsAccidentFinished></vehicleIsAccidentFinished>"); // 运输产生安全事故-是否处理完成
                sb.append("<vehicleIsInsurance></vehicleIsInsurance>"); //保险赔付-是否发生赔付
                sb.append("<vehicleIsInsuranceAmount>0</vehicleIsInsuranceAmount>"); // 保险赔付-赔付金额
                sb.append("<vehicleIsInsuranceAmount>0</vehicleIsInsuranceAmount>"); // 保险赔付-赔付金额
                sb.append("<vehicleIsService></vehicleIsService>");//服务质量投诉-是否发生
                sb.append("<vehicleIsServiceFinished>0</vehicleIsServiceFinished>"); // 服务质量投诉-是否处理完成
                sb.append("<freeText></freeText>");
                sb.append("</stOrder>");
                sb.append("</body>");
                sb.append("</root>");
                return sb.toString();
            }
        }
        return null;
    }

    private Origination getOrigination(Origination location, String resLocation) {
        if (!StringUtils.isEmpty(resLocation)) {
            RestfulResponse<List<Origination>> parseLoc = JSONObject.parseObject(resLocation, new TypeReference<RestfulResponse<List<Origination>>>() {
            });
            List<Origination> originLoc = parseLoc.getData();
            if (CollectionUtils.isNotEmpty(originLoc)) {
                location = originLoc.get(0);
            }
        }
        return location;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void positionUpload(ShipToByLicenseBO shipToByLicenseBO, String token) {

        checkData(shipToByLicenseBO);

        // 查询装车单车牌号
        Shipment shipment = selectById(shipToByLicenseBO.getShipmentId());
        if (shipment == null) {
            throw new BaseException(-1, "找不到运单的信息，请确认！");
        }

        ErpShipToByLicenseBO erpShipToByLicenseBO = new ErpShipToByLicenseBO();
        // 车牌号
        erpShipToByLicenseBO.setLicense(shipment.getTransportationId());
        // 司机名称
        erpShipToByLicenseBO.setDriverName(shipment.getDriverName());
        // 司机电话
        erpShipToByLicenseBO.setMobile(shipment.getDriverPhone());
        // 省份
        erpShipToByLicenseBO.setProvince(shipToByLicenseBO.getProvince());
        // 城市
        erpShipToByLicenseBO.setCity(shipToByLicenseBO.getCity());

        Point point = new Point(shipToByLicenseBO.getDcx(), shipToByLicenseBO.getDcy());
        Point src_ = GeoUtil.convertMars2Earth(point);
        // 经度
        erpShipToByLicenseBO.setDcx(src_.getLon());
        // 纬度
        erpShipToByLicenseBO.setDcy(src_.getLat());

        // 详细地址
        erpShipToByLicenseBO.setLocation(shipToByLicenseBO.getLocation());

        // 发送位置上报请求给 erp
        erpUtil.positionUpload(erpShipToByLicenseBO);

        ShipmentPosition shipmentPosition = new ShipmentPosition();
        // 装车单号
        shipmentPosition.setShipmentCode(shipment.getCode());
        // 经度
        shipmentPosition.setGpsLongitude(new BigDecimal(shipToByLicenseBO.getDcx()));
        // 纬度
        shipmentPosition.setGpsLatitude(new BigDecimal(shipToByLicenseBO.getDcy()));
        // 详细地址信息
        shipmentPosition.setAddrText(shipToByLicenseBO.getLocation());
        // 创建时间
        shipmentPosition.setGmtCreate(new Date());

        shipmentPosition.setTenantId(Long.valueOf(AccountUtil.getAccountInfoFromSecurityContext().getTenantId()));
        // 保存装车单在途信息
        shipmentPositionService.insert(shipmentPosition);

        //shipment--->shipmentdetail-->shiporder
        if (properties.isSendToOTM()) {
            EntityWrapper<ShipmentDetail> ew = new EntityWrapper<>();
            ew.eq("shipment_id", shipment.getId())
                    .eq("is_delete", TableStatusEnum.STATUS_0.getCode())
                    .orderBy("id", false);
            ShipmentDetail detail = shipmentDetailService.selectOne(ew);
            if (detail == null) {
                throw new BaseException("未查询到对应的shipmentDetail信息:" + shipment.getId());
            }
            EntityWrapper<ShipTask> taskEW = new EntityWrapper<>();
            taskEW.eq("code", detail.getShipTaskCode())
                    .eq("is_delete", TableStatusEnum.STATUS_0.getCode())
                    .orderBy("id", false);
            ShipTask shipTask = shipTaskService.selectOne(taskEW);
            if (shipTask == null) {
                throw new BaseException("未查询到对应的ShipTask信息:" + detail.getShipTaskCode());
            }
            EntityWrapper<ShipOrderItem> itemEW = new EntityWrapper<>();
            itemEW.eq("ship_order_code", shipTask.getShipOrderCode())
                    .eq("is_delete", TableStatusEnum.STATUS_0.getCode());
            List<ShipOrderItem> orderItems = orderItemService.selectList(itemEW);
            //从oms 获取指令号
            new Thread(() -> {
                HashMap<String, String> param = Maps.newHashMap();
                param.put("tmsOrderCode", shipTask.getShipOrderCode());
                Order order = orderService.queryOrderFromTms(param);
                if (Objects.nonNull(order)) {
                    if (CollectionUtils.isNotEmpty(orderItems)) {
                        for (ShipOrderItem item : orderItems) {
                            // 发送位置上报回传OTM
                            OTMEvent event = new OTMEvent();
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                            event.setExportKey(shipment.getCode());
                            event.setCallBackUrl(null);
                            event.setEventType(InterfaceEventEnum.BS_ENROUTED.getCode());
                            event.setOccurDate(sdf.format(new Date()));
                            event.setRecdDate(sdf.format(new Date()));
                            event.setDescribe(InterfaceEventEnum.BS_ENROUTED.getDesc());
                            event.setOrderReleaseId(item.getItemSourceKey());
                            event.setShipmentId(order.getCustomerOrderId());
                            event.setProvince(erpShipToByLicenseBO.getProvince());
                            event.setCity(erpShipToByLicenseBO.getCity());
                            event.setSort(1);
                            event.setAddress(erpShipToByLicenseBO.getLocation());
                            event.setGpsLongitude(String.format("%.5f", shipmentPosition.getGpsLongitude()));
                            event.setGpsLatitude(String.format("%.5f", shipmentPosition.getGpsLatitude()));
                            event.setQrCode(null);
                            //传送OTM
                            try {
                                String postJson = HttpClientUtil.postJson(properties.getIntegrationhost() + IntegrationURIEnum.EVENT_URI.getAddress(),
                                        null, JSONObject.toJSONString(event), properties.getSocktTimeOut());
                                LOGGER.info("positionUpload 回传OTM指令号响应结果:{}", postJson);
                            } catch (Exception e) {
                                LOGGER.error("positionUpload 回传OTM指令号超时异常:url:{},params:{}", properties.getIntegrationhost() + IntegrationURIEnum.EVENT_URI.getAddress(), JSONObject.toJSONString(event));

                            }
                        }
                    }
                }

            }).start();
        }


    }

    private void checkData(ShipToByLicenseBO shipToByLicenseBO) {

        if (Objects.isNull(shipToByLicenseBO.getShipmentId())) {
            throw new BaseException(-1, "运单不能为空");
        }

        if (StringUtils.isEmpty(shipToByLicenseBO.getProvince())) {
            throw new BaseException(-1, "省份不能为空");
        }

        if (StringUtils.isEmpty(shipToByLicenseBO.getCity())) {
            throw new BaseException(-1, "城市不能为空");
        }

        if (shipToByLicenseBO.getDcx() == null) {
            throw new BaseException(-1, "经度不能为空");
        }

        if (shipToByLicenseBO.getDcy() == null) {
            throw new BaseException(-1, "玮度不能为空");
        }
    }

    @Override
    public Page<ShipmentListVo> getShipmentListVoByTenanId(Page<Shipment> page, HttpServletRequest
            request) {
        String authHeader = request.getHeader(header);
        Page<ShipmentListVo> pageVo = new Page<>();
        List<ShipmentListVo> shipmentListVos = Lists.newArrayList();
        page.setAsc(false);
        page.setOrderByField("gmt_create");
        Wrapper<Shipment> shipmentWrapper = new EntityWrapper<>();
        if (!StringUtils.isEmpty(page.getCondition().get("tenantId")))
            shipmentWrapper.eq("tenant_id", page.getCondition().get("tenantId"));
        Object gmtCreate = page.getCondition().get("gmtCreate");
        if (!StringUtils.isEmpty(page.getCondition().get("gmtCreate"))) {
            String result = new SimpleDateFormat("yyyy-MM-dd").format(gmtCreate);
            shipmentWrapper.and("date_format(gmt_create,'%Y-%m-%d')= {0}", result);
        }
        String issue = (String) page.getCondition().get("issue");
        String arrive = (String) page.getCondition().get("arrive");
        // 发运状况
        if(!StringUtils.isEmpty(issue)){
            if((TableStatusEnum.STATUS_Y.getCode()).equals(issue)){
                shipmentWrapper.isNotNull("gmt_setoff");
            }else {
                shipmentWrapper.isNull("gmt_setoff");
            }
        }
        // 运抵状况
        if(!StringUtils.isEmpty(arrive)){
            if((TableStatusEnum.STATUS_Y.getCode()).equals(arrive)){
                shipmentWrapper.isNotNull("gmt_deliver");
            }else {
                shipmentWrapper.isNull("gmt_deliver");
            }
        }
        List<Shipment> shipments = baseMapper.getShipmentByPage(page, shipmentWrapper);
        shipments.forEach(shipment -> {
            ShipmentListVo shipmentListVo = new ShipmentListVo();
            BeanUtils.copyProperties(shipment, shipmentListVo);
            List<ShipTaskCountBo> shipTaskCountBos = shipTaskService.getlspWaybill(shipment.getId());
            if (!CollectionUtils.isEmpty(shipTaskCountBos)) {
                shipTaskCountBos.forEach(shipTaskCountBo -> {
                    LocationVo start = locationService.getLocationById(Long.parseLong(shipTaskCountBo.getOriginLocationCode()));
                    LocationVo end = locationService.getLocationById(Long.parseLong(shipTaskCountBo.getDestLocationCode()));
                    if (!Objects.isNull(start)) {
                        shipTaskCountBo.setStartAddress(start.getLabel());
                    }
                    if (!Objects.isNull(end)) {
                        shipTaskCountBo.setEndAddress(end.getLabel());
                    }
                });
            }
            shipmentListVo.setShipTaskCountBos(shipTaskCountBos);
            shipmentListVos.add(shipmentListVo);
        });
        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(shipmentListVos);
        return pageVo;
    }

    @Override
    public Boolean driverWaybill(Long driverId) {
        Wrapper<Shipment> shipmentWrapper = new EntityWrapper<>();
        shipmentWrapper.eq("driver_id", driverId)
                .orderBy("id", false);
        List<Shipment> shipmentLists = this.selectList(shipmentWrapper);
        if (CollectionUtils.isNotEmpty(shipmentLists)) {
            for (Shipment shipmentList : shipmentLists) {
                if (shipmentList.getGmtDeliver() == null) {
                    //只要有未完成运单
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public Shipment getDriverShipmentnotenant(Long id) {
        return baseMapper.getDriverShipmentnotenant(id);
    }

    @Override
    public void peopleSendDepartureConfirmation(HuiyuncheCancleDTO infoDTO, String token) {
        if (Objects.isNull(infoDTO) && StringUtils.isEmpty(infoDTO.getOrderCode())) {
            throw new BaseException(-1, "指令号不能为空");
        }
        Wrapper<Shipment> wrapper = new EntityWrapper<>();
        wrapper.eq("ship_source_key", infoDTO.getOrderCode());
        Shipment shipment = this.selectOne(wrapper);
        if (Objects.isNull(shipment)) {
            throw new BaseException(-1, "装车单不存在");
        }
        shipment.setGmtSetoff(new Date());
        this.updateById(shipment);
        Wrapper<ShipmentDetail> ew = new EntityWrapper<>();
        ew.eq("shipment_id", shipment.getId());
        ShipmentDetail shipmentDetail = shipmentDetailService.selectOne(ew);
        EntityWrapper<ShipTask> taskEW = new EntityWrapper<>();
        taskEW.eq("code", shipmentDetail.getShipTaskCode());
        ShipTask shipTask = shipTaskService.selectOne(taskEW);
        shipTask.setGmtStart(new Date());
        shipTaskService.updateById(shipTask);

        new Thread(() -> {
            PricePurchaseDTO pricePurchaseDTO = new PricePurchaseDTO();
            pricePurchaseDTO.setShipmentCode(shipment.getCode());
            pricePurchaseDTO.setShipTaskCode(shipTask.getCode());
            pricePurchaseDTO.setShipmentDate(infoDTO.getDtshipdate());
            pricePurchaseDTO.setLoadStatus(TableStatusEnum.STATUS_10.getCode());
            pricePurchaseDTO.setCreateFrom(TableStatusEnum.STATUS_20.getCode());
            List<NameValuePair> headNamePairs = Lists.newArrayList();
            headNamePairs.add(new BasicNameValuePair("Authorization", token));
            String strReturn = null;
            try {
                strReturn = HttpClientUtil.postJson(importPurchaseAndDtl, headNamePairs,
                        JSON.toJSONString(pricePurchaseDTO), socketTimeout);
                LOGGER.info("人送发运-->连接BMS 发运生成支付单据url:{},param:{},result:{}", importPurchaseAndDtl, JSON.toJSONString(pricePurchaseDTO), strReturn);
                if (StringUtils.isEmpty(strReturn)) {
                    throw new BaseException("人送发运-->连接BMS 生成支付单据未响应,请稍后再试");
                } else {
                    JSONObject parseObject = JSONObject.parseObject(strReturn);
                    int code = parseObject.getIntValue("code");
                    if (code != 0) {
                        throw new BaseException("人送发运-->连接BMS失败" + parseObject.getString("message"));
                    }
                }
            } catch (Exception e) {
                LOGGER.error("人送发运-->连接BMS 生成支付单据连接异常: {}", e);
                throw new BaseException("人送发运-->连接BMS 生成支付单据连接异常,请稍后再试");
            }
        }).start();
    }

    @Override
    public void peopleSendShippingTo(HuiyuncheCancleDTO infoDTO) {
        if (StringUtils.isEmpty(infoDTO.getOrderCode())) {
            throw new BaseException(-1, "指令号不能为空");
        }
        Wrapper<Shipment> wrapper = new EntityWrapper<>();
        wrapper.eq("ship_source_key", infoDTO.getOrderCode());
        Shipment shipment = this.selectOne(wrapper);
        if (Objects.isNull(shipment)) {
            throw new BaseException(-1, "装车单不存在");
        }
        shipment.setGmtDeliver(new Date());
        this.updateById(shipment);
        Wrapper<ShipmentDetail> ew = new EntityWrapper<>();
        ew.eq("shipment_id", shipment.getId());
        ShipmentDetail shipmentDetail = shipmentDetailService.selectOne(ew);
        EntityWrapper<ShipTask> taskEW = new EntityWrapper<>();
        taskEW.eq("code", shipmentDetail.getShipTaskCode());
        ShipTask shipTask = shipTaskService.selectOne(taskEW);
        shipTask.setGmtFinish(new Date());
        shipTaskService.updateById(shipTask);
    }

    @Override
    public List<Shipment> selectListNotenant(EntityWrapper<Shipment> sew) {
        return baseMapper.selectListNotenant(sew);
    }

    @Override
    public Shipment selectOneNoTenant(EntityWrapper<Shipment> shipEW) {
        return baseMapper.selectOneNoTenant(shipEW);
    }

    @Override
    public Shipment selectShipmentByShTaskCode(String taskCode) {
        return baseMapper.selectShipmentByShTaskCode(taskCode);
    }

    @Override
    public List<Shipment> queryShipDataWms(EntityWrapper<Shipment> stEW) {
        return baseMapper.queryShipDataWms(stEW);
    }

    @Override
    public Page<ShipmentListVo> getShipAttachlist(Page<Shipment> page) {
        Page<ShipmentListVo> pageVo = new Page<>();
        List<ShipmentListVo> shipmentListVos = Lists.newArrayList();
        page.setAsc(false);
        page.setOrderByField("gmt_create");
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<Shipment> ew = new EntityWrapper<>();
        if (condition != null && !condition.isEmpty()) {
            if(null != condition.get("shipSourceKey") && !StringUtils.isEmpty(condition.get("shipSourceKey"))){
                ew.like("ship_source_key", condition.get("shipSourceKey").toString());
            }
            if(null != condition.get("transportationId") && !StringUtils.isEmpty(condition.get("transportationId"))){
                ew.like("transportation_id", condition.get("transportationId").toString());
            }
            if(null != condition.get("transTypeId") && !StringUtils.isEmpty(condition.get("transTypeId"))){
                ew.eq("trans_type_id", condition.get("transTypeId"));
            }
            if(null != condition.get("isPhotoUpload") && !StringUtils.isEmpty(condition.get("isPhotoUpload"))){
                ew.eq("isPhotoUpload", condition.get("isPhotoUpload"));
            }
            if(null != condition.get("gmtCreateStart") && !StringUtils.isEmpty(condition.get("gmtCreateStart"))){
                ew.ge("gmt_create", condition.get("gmtCreateStart"));
            }
            if(null != condition.get("gmtCreateEnd") && !StringUtils.isEmpty(condition.get("gmtCreateEnd"))){
                ew.le("gmt_create", condition.get("gmtCreateEnd"));
            }
            if(null != condition.get("gmtSetoffStart") && !StringUtils.isEmpty(condition.get("gmtSetoffStart"))){
                ew.ge("gmt_setoff", condition.get("gmtSetoffStart"));
            }
            if(null != condition.get("gmtSetoffEnd") && !StringUtils.isEmpty(condition.get("gmtSetoffEnd"))){
                ew.le("gmt_setoff", condition.get("gmtSetoffEnd"));
            }

        }
        ew.eq("is_delete",0);
        List<Shipment> shipments = baseMapper.getShipAttachlist(page, ew);
        List<TransportationTypeDTO> transTypes = mdmUtil.getAllTransType();
        shipments.forEach(shipment->{
            // 对接MDM获取运输方式
            if(null != shipment.getTransTypeId() && !StringUtils.isEmpty(shipment.getTransTypeId())
                    && null != transTypes && !transTypes.isEmpty()){
                transTypes.forEach(transType ->{
                    if(shipment.getTransTypeId().equals(transType.getId())){
                        shipment.setTransType(transType.getValue());
                        return;
                    }
                });
            }

            ShipmentListVo shipmentListVo = new ShipmentListVo();
            BeanUtils.copyProperties(shipment, shipmentListVo);
            shipmentListVos.add(shipmentListVo);
        });
        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(shipmentListVos);
        return pageVo;
    }

    @Override
    public void shipToProvince(String shipmentId,String token) {
        String[] split = shipmentId.split(",");
        for (String s : split) {
            Wrapper<Shipment> wrapper = new EntityWrapper<>();
            wrapper.eq("ship_source_key", s.trim().replace("\n","")).eq("is_delete", TableStatusEnum.STATUS_0.getCode());
            Shipment shipment = this.selectOne(wrapper);
            List<NameValuePair> headNamePairs = Lists.newArrayList();
            headNamePairs.add(new BasicNameValuePair("Authorization", token));
            String result = HttpClientUtil.get(isUnlcnFleetDriverUrl + "/" + shipment.getDriverId(), headNamePairs, null, properties.getSocktTimeOut());
            LOGGER.info("result (判断司机是否是中联自有车队返回结果) url:{},erpResult:{}", isUnlcnFleetDriverUrl + "/" + shipment.getDriverId(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String data = jsonObject.getString("data");
            if (!StringUtils.isEmpty(data)) {
                String xmlProv = getXmlProv(shipment, token);
                ArrayList<NameValuePair> headers = Lists.newArrayList();
                headers.add(new BasicNameValuePair("Authorization", token));
                HashMap<String, String> params = Maps.newHashMap();
                params.put("xml", xmlProv);
                params.put("sourceKey", shipment.getShipSourceKey());
                LOGGER.info("推送无车承运人信息--start url:{},param:{}", properties.getIntegrationhost() + sendXMLShipToProvinceUrl, xmlProv);
                if (!StringUtils.isEmpty(xmlProv)) {
                    new Thread(() -> {
                        RedisLogUtil.addSysLogs(SystemEnum.OMS.getCode(),SystemEnum.INTEGRATION.getCode(),"无车承运人推送省"+shipment.getShipSourceKey(), JSON.toJSONString(params),"/tmsAPI/sendXMLShipToProv",1,1,null,isTest);

                        String res = HttpClientUtil.post(properties.getIntegrationhost() + sendXMLShipToProvinceUrl, headers, params, properties.getSocktTimeOut());
                        LOGGER.info("推送无车承运人信息--start url:{},key:{},result:{}", properties.getIntegrationhost() + sendXMLShipToProvinceUrl, shipment.getShipSourceKey(), res);
                        System.err.println("推送是否成功"+"==="+shipment.getShipSourceKey()+"==="+ res);
                    }).start();

                }
            }
        }
    }

    @Override
    public Page<ShipmentListInfoVo> getShipmentListVoByFleetId(Page<Shipment> page, String token) {
        Page<ShipmentListInfoVo> pageVo = new Page<>();

        Map<String, Object> condition = page.getCondition();

        EntityWrapper<Shipment> ew = this.getEntityWrapper(condition, token);

        List<ShipmentListInfoVo> maps = baseMapper.getShipTaskByFleetId(page, ew);

        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(maps);
        return pageVo;
    }

    public Object getLspFleet(String token, String mobile) {
        Object fleetIdStrings;
        List<NameValuePair> headNamePairs = org.assertj.core.util.Lists.newArrayList();
        headNamePairs.add(new BasicNameValuePair("Authorization", token));
        List<Map<String,Object>> fleetResults = null;
        try {
            LOGGER.info("getShipmentListVoByFleetId info url:{},params:{} ", getFleetListByLspMobileUrl, mobile);
            String fleetResult = HttpClientUtil.postJson(getFleetListByLspMobileUrl,headNamePairs, mobile, socketTimeout);
            LOGGER.info("getShipmentListVoByFleetId result {} ", fleetResult);
            if(null == fleetResult || "".equals(fleetResult)){
                throw new BaseException("获取承运商车队信息错误，请稍后在试！");
            }
            RestfulResponse<List<Map<String, Object>>> response = JSONObject.parseObject(fleetResult, new TypeReference<RestfulResponse<List<Map<String, Object>>>>() {
            });
            if(null != response && null != response.getData()){
                fleetResults = response.getData();
            }
        } catch (Exception e) {
            LOGGER.error("getShipmentListVoByFleetId url:{},params:{} 连接超时:{}", getFleetListByLspMobileUrl, mobile, e);
            throw new BaseException(e.getMessage());
        }

        if(CollectionUtils.isEmpty(fleetResults)){
            throw new BaseException(-1,"您还没有车队！");
        }
        StringBuffer sb = new StringBuffer();
        for(Map<String,Object> map : fleetResults){
            sb.append(map.get("id") + ",");
        }
        fleetIdStrings = sb.substring(0, sb.length() - 1);
        return fleetIdStrings;
    }

    private EntityWrapper<Shipment> getShipmentEntityWrapper(Map<String, Object> condition,String token) {

        if (condition == null || condition.isEmpty()) {
            throw new BaseException("参数为空！");
        }
        // 获取登陆者信息
        JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
        EntityWrapper<Shipment> ew = new EntityWrapper<>();
        // 不是中联管理账号
        if(!"1".equals(account.getTenantId())){
            Object fleetIdStrings = condition.get("fleetId");
            if (Objects.isNull(fleetIdStrings) || StringUtils.isEmpty(fleetIdStrings.toString())) {
                String mobile = (String)condition.get("mobile");
                if(null == mobile || "".equals(mobile)){throw new BaseException("您还不是车队管理员！");}
                // 对接lspm拿取承运商车队信息
                fleetIdStrings = getLspFleet(token, mobile);
                if(null == fleetIdStrings || "".equals(fleetIdStrings)){throw new BaseException("您还不是车队管理员！");}
            }
            List<String> fleetIds = Arrays.asList(fleetIdStrings.toString().split(","));
            ew.in("fleetId", fleetIds);
        }

        String driverPhone = (String)condition.get("driverPhone");
        String driverName = (String)condition.get("driverName");
        String shipSourceKey = (String) condition.get("shipSourceKey");
        String transportationId = (String) condition.get("transportationId");
        String issue = (String) condition.get("issue");
        String arrive = (String) condition.get("arrive");
        String actualIssue = (String) condition.get("actualIssue");
        // 手机号
        if(null != driverPhone && !"".equals(driverPhone)){
            ew.like("driverPhone",driverPhone);
        }
        // 司机名
        if(null != driverName && !"".equals(driverName)){
            ew.like("driverName",driverName);
        }
        // 指令号
        if(null != shipSourceKey && !"".equals(shipSourceKey)){
            ew.eq("shipSourceKey",shipSourceKey);
        }
        // 车牌号
        if(null != transportationId && !"".equals(transportationId)){
            ew.like("transportationId",transportationId);
        }
        // 发运状况
        if(null != issue && !"".equals(issue)){
            if("y".equals(issue)){
                ew.isNotNull("gmtStart");
            }else {
                ew.isNull("gmtStart");
            }
        }
        // 运抵状况
        if(null != arrive && !"".equals(arrive)){
            if("y".equals(arrive)){
                ew.isNotNull("gmtFinish");
            }else {
                ew.isNull("gmtFinish");
            }
        }
        // 实际发运状况
        if(null != actualIssue && !"".equals(actualIssue)){
            if("y".equals(actualIssue)){
                ew.isNotNull("wmsShipTime");
            }else {
                ew.isNull("wmsShipTime");
            }
        }
        return ew;
    }

    @Override
    public List<ShipmentListInfoVo> exportShipByFleetId(Map<String, Object> condition, String token) {
        EntityWrapper<Shipment> ew = this.getEntityWrapper(condition, token);
        List<ShipmentListInfoVo> maps=baseMapper.exportShipByFleetId(ew);
        return maps;
    }

    @Override
    public Boolean lspWaybill(String lspId) {
        Wrapper<Shipment> shipmentWrapper = new EntityWrapper<>();
        shipmentWrapper.eq("lsp_id", lspId).eq("is_delete","0")
                .orderBy("id", false);
        List<Shipment> shipmentLists = this.selectList(shipmentWrapper);
        if (CollectionUtils.isNotEmpty(shipmentLists)) {
            for (Shipment shipmentList : shipmentLists) {
                if (shipmentList.getGmtDeliver() == null) {
                    //只要有未完成运单
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public Boolean fleetWaybill(String fleetId) {
        Wrapper<Shipment> shipmentWrapper = new EntityWrapper<>();
        shipmentWrapper.eq("fleet_id", fleetId).eq("is_delete","0")
                .orderBy("id", false);
        List<Shipment> shipmentLists = this.selectList(shipmentWrapper);
        if (CollectionUtils.isNotEmpty(shipmentLists)) {
            for (Shipment shipmentList : shipmentLists) {
                if (shipmentList.getGmtDeliver() == null) {
                    //只要有未完成运单
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public List<String> getShipSourceKeys() {
       return baseMapper.queryShipSourceKeys();
    }

    /**
     * 查询运单的 查询条件
     * @param condition
     * @param token
     * @return
     */
    public EntityWrapper<Shipment> getEntityWrapper(Map<String, Object> condition, String token){
        //处理查询条件
        EntityWrapper<Shipment> ew = getShipmentEntityWrapper(condition, token);
        if (condition != null && !condition.isEmpty()) {
            if (null != condition.get("gmtDeliverStart") && !StringUtils.isEmpty(condition.get("gmtDeliverStart"))) {
                ew.ge("gmtDeliver", condition.get("gmtDeliverStart"));
            }
            if (null != condition.get("gmtDeliverEnd") && !StringUtils.isEmpty(condition.get("gmtDeliverEnd"))) {
                ew.le("gmtDeliver", condition.get("gmtDeliverEnd"));
            }
            if (null != condition.get("gmtCreateStart") && !StringUtils.isEmpty(condition.get("gmtCreateStart"))) {
                ew.ge("gmtCreate", condition.get("gmtCreateStart"));
            }
            if (null != condition.get("gmtCreateEnd") && !StringUtils.isEmpty(condition.get("gmtCreateEnd"))) {
                ew.le("gmtCreate", condition.get("gmtCreateEnd"));
            }
            if (null != condition.get("gmtStartStart") && !StringUtils.isEmpty(condition.get("gmtStartStart"))) {
                ew.ge("gmtStart", condition.get("gmtStartStart"));
            }
            if (null != condition.get("gmtStartEnd") && !StringUtils.isEmpty(condition.get("gmtStartEnd"))) {
                ew.le("gmtStart", condition.get("gmtStartEnd"));
            }
            if (null != condition.get("startAddress") && !StringUtils.isEmpty(condition.get("startAddress"))) {
                ew.like("startAddress", condition.get("startAddress").toString());
            }
            if (null != condition.get("endAddress") && !StringUtils.isEmpty(condition.get("endAddress"))) {
                ew.like("endAddress", condition.get("endAddress").toString());
            }
            if (null != condition.get("fleetName") && !StringUtils.isEmpty(condition.get("fleetName"))) {
                ew.like("fleetName", condition.get("fleetName").toString());
            }
            if (null != condition.get("issueItemId") && !StringUtils.isEmpty(condition.get("issueItemId"))) {
                String[] vins = condition.get("issueItemId").toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("issueItemId", vins);
            }
            if (null != condition.get("ciamsId") && !StringUtils.isEmpty(condition.get("ciamsId"))) {
                ew.like("ciamsId", condition.get("ciamsId").toString());
            }
            if (null != condition.get("cusWaybillId") && !StringUtils.isEmpty(condition.get("cusWaybillId"))) {
                ew.like("cusWaybillId", condition.get("cusWaybillId").toString());
            }
            ew.notLike("shipSourceKey","K");
        }
        return ew;
    }

}
